﻿using System.Collections.Generic;
using System;
using Windows.Devices.Bluetooth;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Enumeration;
using Windows.Foundation;
using Windows.Networking;
using Windows.Networking.Proximity;
using Windows.Networking.Sockets;
using Windows.Security.Cryptography;
using Windows.Storage.Streams;
using YH.Bluetooth;
using static System.Net.Mime.MediaTypeNames;
using Newtonsoft.Json;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace BleSolution
{
    public class BleCoreNew
    {
        private Boolean asyncLock = false;

        /// <summary>
        /// 搜索蓝牙设备对象
        /// </summary>
        private DeviceWatcher deviceWatcher;

        /// <summary>
        /// 当前连接的服务
        /// </summary>
        public GattDeviceService CurrentService { get; set; }

        /// <summary>
        /// 当前连接的蓝牙设备
        /// </summary>
        public BluetoothLEDevice CurrentDevice { get; set; }

        /// <summary>
        /// 写特征对象
        /// </summary>
        public GattCharacteristic CurrentWriteCharacteristic { get; set; }

        /// <summary>
        /// 通知特征对象
        /// </summary>
        public GattCharacteristic CurrentNotifyCharacteristic { get; set; }

        /// <summary>
        /// 特性通知类型通知启用
        /// </summary>
        private const GattClientCharacteristicConfigurationDescriptorValue CHARACTERISTIC_NOTIFICATION_TYPE = GattClientCharacteristicConfigurationDescriptorValue.Notify;

        /// <summary>
        /// 存储检测到的设备
        /// </summary>
        private List<BluetoothLEDevice> DeviceList = new List<BluetoothLEDevice>();

        /// <summary>
        /// 定义搜索蓝牙设备委托
        /// </summary>
        public delegate void DeviceWatcherChangedEvent(MsgType type, BluetoothLEDevice bluetoothLEDevice);

        /// <summary>
        /// 搜索蓝牙事件
        /// </summary>
        public event DeviceWatcherChangedEvent DeviceWatcherChanged;

        /// <summary>
        /// 获取服务委托
        /// </summary>
        public delegate void GattDeviceServiceAddedEvent(GattDeviceService gattDeviceService);

        /// <summary>
        /// 获取服务事件
        /// </summary>
        public event GattDeviceServiceAddedEvent GattDeviceServiceAdded;

        /// <summary>
        /// 获取特征委托
        /// </summary>
        public delegate void CharacteristicAddedEvent(GattCharacteristic gattCharacteristic);

        /// <summary>
        /// 获取特征事件
        /// </summary>
        public event CharacteristicAddedEvent CharacteristicAdded;

        /// <summary>
        /// 提示信息委托
        /// </summary>
        public delegate void MessAgeChangedEvent(MsgType type, string message, byte[] data = null);

        /// <summary>
        /// 提示信息事件
        /// </summary>
        public event MessAgeChangedEvent MessAgeChanged;

        /// <summary>
        /// 当前连接的蓝牙Mac
        /// </summary>
        private string CurrentDeviceMAC { get; set; }
        /// <summary>
        /// 接收数据的控制命令
        /// </summary>
        private List<string> commandCallback = new List<string> { "Devices Found", "Chars Found", "Can not find the device",
            "OK+LOST", "ab02d121cc", "7e01" };
        /// <summary>
        /// 收到的字符串
        /// </summary>
        private string m_receive_data = "";

        private DeviceModel deviceModel = new DeviceModel();
        /// <summary>
        /// 解析数据的类
        /// </summary>
        SLPWrapper slp = new SLPWrapper();

        private readonly IWebSocketServerService _webSocketServerService;


        /// <summary>
        /// 蓝牙适配器
        /// </summary>
        private Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher deviceWatcherNew;


        public BleCoreNew(IWebSocketServerService webSocketServerService)
        {
            LogHelper.WriteLog($"初始化结果: {slp.InitializeSLP()}");
            _webSocketServerService = webSocketServerService;
        }
        ~BleCoreNew()
        {
            LogHelper.WriteLog($"清理结果: {slp.DestroySLP()}");
        }


        public void StartBleDeviceWatcherNew() 
        {
            try
            {

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                LogHelper.WriteLog(ex);
            }
        }


        /// <summary>
        /// 搜索蓝牙设备
        /// </summary>
        public void StartBleDeviceWatcher()
        {
            try
            {
                string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected", "System.Devices.Aep.Bluetooth.Le.IsConnectable" };
                string aqsAllBluetoothLEDevices = "(System.Devices.Aep.ProtocolId:=\"{bb7bb05e-5972-42b5-94fc-76eaa7084d49}\")";

                this.deviceWatcher =
                        DeviceInformation.CreateWatcher(
                            aqsAllBluetoothLEDevices,
                            requestedProperties,
                            DeviceInformationKind.AssociationEndpoint);

                //this.deviceWatcher = DeviceInformation.CreateWatcher();

                // Register event handlers before starting the watcher.
                this.deviceWatcher.Added += this.DeviceWatcher_Added;
                this.deviceWatcher.Stopped += this.DeviceWatcher_Stopped;
                this.deviceWatcher.Start();
                string msg = "自动发现设备中..";

                this.MessAgeChanged(MsgType.NotifyTxt, msg);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }

        /// <summary>
        /// 停止搜索蓝牙
        /// </summary>
        public void StopBleDeviceWatcher()
        {
            try
            {
                if (this.deviceWatcher != null)
                {
                    this.deviceWatcher.Stop();
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }

        /// <summary>
        /// 获取发现的蓝牙设备
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation args)
        {
            try
            {
                this.MessAgeChanged(MsgType.NotifyTxt, "发现设备:" + args.Id);
                this.Matching(args.Id);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }

        /// <summary>
        /// 停止搜索蓝牙设备
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void DeviceWatcher_Stopped(DeviceWatcher sender, object args)
        {
            try
            {
                string msg = "自动发现设备停止";
                this.MessAgeChanged(MsgType.NotifyTxt, msg);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }

        /// <summary>
        /// 匹配
        /// </summary>
        /// <param name="Device"></param>
        public void StartMatching(BluetoothLEDevice Device)
        {
            try
            {
                this.CurrentDevice = Device;
                this.Connect();
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }

        /// <summary>
        /// 获取蓝牙服务
        /// </summary>
        public async void FindService()
        {
            try
            {
                var GattServices = this.CurrentDevice.GattServices;
                foreach (GattDeviceService ser in GattServices)
                {
                    if (ser.Uuid == new Guid("0000fff0-0000-1000-8000-00805f9b34fb"))
                    {

                    }
                    this.GattDeviceServiceAdded(ser);
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }
        /// <summary>
        /// 获取特性
        /// </summary>
        public async void FindCharacteristic(GattDeviceService gattDeviceService)
        {
            try
            {
                this.CurrentService = gattDeviceService;
                foreach (var c in gattDeviceService.GetAllCharacteristics())
                {
                    this.CharacteristicAdded(c);
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }

        }

        /// <summary>
        /// 获取操作
        /// </summary>
        /// <returns></returns>
        public async Task SetOpteron(GattCharacteristic gattCharacteristic)
        {
            try
            {
                if (gattCharacteristic.CharacteristicProperties == GattCharacteristicProperties.Write)
                {
                    this.CurrentWriteCharacteristic = gattCharacteristic;
                }
                if (gattCharacteristic.CharacteristicProperties == GattCharacteristicProperties.Notify)
                {
                    this.CurrentNotifyCharacteristic = gattCharacteristic;
                }
                if ((uint)gattCharacteristic.CharacteristicProperties == 26)
                { }

                if (gattCharacteristic.CharacteristicProperties == (GattCharacteristicProperties.Notify | GattCharacteristicProperties.Read | GattCharacteristicProperties.Write))
                {
                    this.CurrentWriteCharacteristic = gattCharacteristic;

                    this.CurrentNotifyCharacteristic = gattCharacteristic;
                    this.CurrentNotifyCharacteristic.ProtectionLevel = GattProtectionLevel.Plain;
                    this.CurrentNotifyCharacteristic.ValueChanged += Characteristic_ValueChanged;
                    await this.EnableNotifications(CurrentNotifyCharacteristic);
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }
        /// <summary>
        /// 监听接收特征值服务
        /// </summary>
        /// <returns></returns>
        public async Task SetReceiveOpteron(GattCharacteristic gattCharacteristic)
        {
            try
            {
                if (gattCharacteristic.CharacteristicProperties == GattCharacteristicProperties.Notify)
                {
                    this.CurrentNotifyCharacteristic = gattCharacteristic;
                }

                if (gattCharacteristic.CharacteristicProperties == (GattCharacteristicProperties.Notify))
                {
                    this.CurrentNotifyCharacteristic = gattCharacteristic;
                    this.CurrentNotifyCharacteristic.ProtectionLevel = GattProtectionLevel.Plain;
                    this.CurrentNotifyCharacteristic.ValueChanged += Characteristic_ValueChanged;
                    await this.EnableNotifications(CurrentNotifyCharacteristic);
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }
        /// <summary>
        /// 监听发送特征值服务
        /// </summary>
        /// <returns></returns>
        public async Task SetSendOpteron(GattCharacteristic gattCharacteristic)
        {
            try
            {
                if (gattCharacteristic.CharacteristicProperties == GattCharacteristicProperties.Write)
                {
                    this.CurrentWriteCharacteristic = gattCharacteristic;
                }
                if (gattCharacteristic.CharacteristicProperties == GattCharacteristicProperties.Notify)
                {
                    this.CurrentNotifyCharacteristic = gattCharacteristic;
                }

                if (gattCharacteristic.CharacteristicProperties == (GattCharacteristicProperties.Notify | GattCharacteristicProperties.Write))
                {
                    this.CurrentWriteCharacteristic = gattCharacteristic;

                    this.CurrentNotifyCharacteristic = gattCharacteristic;
                    this.CurrentNotifyCharacteristic.ProtectionLevel = GattProtectionLevel.Plain;
                    this.CurrentNotifyCharacteristic.ValueChanged += Characteristic_ValueChanged;
                    await this.EnableNotifications(CurrentNotifyCharacteristic);
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }
        /// <summary>
        /// 停止接收数据
        /// </summary>
        public void StopReceive()
        {
            try
            {
                this.CurrentNotifyCharacteristic.ValueChanged -= Characteristic_ValueChanged;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
        /// <summary>
        /// 开始接收数据
        /// </summary>
        public void SstartReceive()
        {
            try
            {
                this.CurrentNotifyCharacteristic.ValueChanged += Characteristic_ValueChanged;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
        /// <summary>
        /// 连接蓝牙
        /// </summary>
        /// <returns></returns>
        private async Task Connect()
        {
            try
            {
                byte[] _Bytes1 = BitConverter.GetBytes(this.CurrentDevice.BluetoothAddress);
                Array.Reverse(_Bytes1);
                this.CurrentDeviceMAC = BitConverter.ToString(_Bytes1, 2, 6).Replace('-', ':').ToLower();

                string msg = "正在连接设备<" + this.CurrentDeviceMAC + ">..";
                this.MessAgeChanged(MsgType.NotifyTxt, msg);
                this.CurrentDevice.ConnectionStatusChanged += this.CurrentDevice_ConnectionStatusChanged;
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }

        /// <summary>
        /// 搜索到的蓝牙设备
        /// </summary>
        /// <returns></returns>
        private async Task Matching(string Id)
        {
            try
            {
                BluetoothLEDevice.FromIdAsync(Id).Completed = async (asyncInfo, asyncStatus) =>
                {
                    if (asyncStatus == AsyncStatus.Completed)
                    {
                        BluetoothLEDevice bleDevice = asyncInfo.GetResults();
                        this.DeviceList.Add(bleDevice);
                        this.DeviceWatcherChanged(MsgType.BleDevice, bleDevice);
                    }
                };
            }
            catch (Exception e)
            {
                string msg = "没有发现设备" + e.ToString();
                this.MessAgeChanged(MsgType.NotifyTxt, msg);
                this.StartBleDeviceWatcher();
            }
        }

        /// <summary>
        /// 主动断开连接
        /// </summary>
        /// <returns></returns>
        public void Dispose()
        {
            try
            {
                CurrentDeviceMAC = null;
                CurrentService?.Dispose();
                CurrentDevice?.Dispose();
                CurrentDevice = null;
                CurrentService = null;
                CurrentWriteCharacteristic = null;
                CurrentNotifyCharacteristic = null;
                MessAgeChanged(MsgType.NotifyTxt, "主动断开连接");
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }
        /// <summary>
        /// 当前设备的连接状态发生变化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void CurrentDevice_ConnectionStatusChanged(BluetoothLEDevice sender, object args)
        {
            try
            {
                if (sender.ConnectionStatus == BluetoothConnectionStatus.Disconnected && CurrentDeviceMAC != null)
                {
                    string msg = "设备已断开,自动重连";
                    MessAgeChanged(MsgType.NotifyTxt, msg);
                    if (!asyncLock)
                    {
                        asyncLock = true;
                        this.CurrentDevice.Dispose();
                        this.CurrentDevice = null;
                        CurrentService = null;
                        CurrentWriteCharacteristic = null;
                        CurrentNotifyCharacteristic = null;
                        SelectDeviceFromIdAsync(CurrentDeviceMAC);
                    }
                }
                else
                {
                    string msg = "设备已连接";
                    MessAgeChanged(MsgType.NotifyTxt, msg);
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }

        /// <summary>
        /// 按MAC地址直接组装设备ID查找设备
        /// </summary>
        public async Task SelectDeviceFromIdAsync(string MAC)
        {
            try
            {
                CurrentDeviceMAC = MAC;
                CurrentDevice = null;
                BluetoothAdapter.GetDefaultAsync().Completed = async (asyncInfo, asyncStatus) =>
                {
                    if (asyncStatus == AsyncStatus.Completed)
                    {
                        BluetoothAdapter mBluetoothAdapter = asyncInfo.GetResults();
                        byte[] _Bytes1 = BitConverter.GetBytes(mBluetoothAdapter.BluetoothAddress);//ulong转换为byte数组
                        Array.Reverse(_Bytes1);
                        string macAddress = BitConverter.ToString(_Bytes1, 2, 6).Replace('-', ':').ToLower();
                        string Id = "BluetoothLE#BluetoothLE" + macAddress + "-" + MAC;
                        await Matching(Id);
                    }
                };
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }

        /// <summary>
        /// 设置特征对象为接收通知对象
        /// </summary>
        /// <param name="characteristic"></param>
        /// <returns></returns>
        public async Task EnableNotifications(GattCharacteristic characteristic)
        {
            try
            {
                string msg = "收通知对象=" + CurrentDevice.ConnectionStatus;
                this.MessAgeChanged(MsgType.NotifyTxt, msg);

                characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(CHARACTERISTIC_NOTIFICATION_TYPE).Completed = async (asyncInfo, asyncStatus) =>
                {
                    if (asyncStatus == AsyncStatus.Completed)
                    {
                        GattCommunicationStatus status = asyncInfo.GetResults();
                        if (status == GattCommunicationStatus.Unreachable)
                        {
                            msg = "设备不可用";
                            this.MessAgeChanged(MsgType.NotifyTxt, msg);
                            if (CurrentNotifyCharacteristic != null && !asyncLock)
                            {
                                await this.EnableNotifications(CurrentNotifyCharacteristic);
                            }
                        }
                        asyncLock = false;
                        msg = "设备连接状态" + status;
                        this.MessAgeChanged(MsgType.NotifyTxt, msg);
                    }
                };
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }

        /// <summary>
        /// 接受到蓝牙数据
        /// </summary>
        private void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
        {
            try
            {
                byte[] data;
                CryptographicBuffer.CopyToByteArray(args.CharacteristicValue, out data);
                string str = BitConverter.ToString(data);
                this.MessAgeChanged(MsgType.BleData, str, data);
                LogHelper.WriteLog("收到的字符串数据--->>" + str);
                string my_low_str = new string(str.Where(c => c != '-').ToArray()).ToLower();
                m_receive_data += my_low_str;
                if (m_receive_data.Contains(commandCallback[4]))
                {
                    deviceModel.IsEegConnect = true;
                    m_receive_data = "";
                }
                if (deviceModel.IsEegConnect)
                {
                    int my_index = m_receive_data.IndexOf(commandCallback[5]);
                    if (my_index > -1)
                    {
                        int my_end_index = m_receive_data.Length / 68;
                        for (int i = 0; i < my_end_index; i++)
                        {
                            // 拼接数据
                            string my_text = m_receive_data.Substring(0, 68);
                            // 清理已读取的数据 eegData
                            m_receive_data = m_receive_data.Substring(my_text.Length);
                            //去掉包头数据
                            string my_t = my_text.Substring(6, my_text.Length - 6);
                            // 移除所有非十六进制字符（如空格、破折号等）
                            string cleanedHexString = Regex.Replace(my_t, "[^0-9A-Fa-f]", "");

                            // 确保字符串长度是偶数，如果不是，则在末尾添加 '0'
                            if (cleanedHexString.Length % 2 != 0)
                            {
                                cleanedHexString += "0";
                            }

                            // 分割字符串为长度为2的子串，并将其转换为字节数组
                            byte[] byteArray = Enumerable.Range(0, cleanedHexString.Length)
                                                         .Where(x => x % 2 == 0)
                                                         .Select(x => Convert.ToByte(cleanedHexString.Substring(x, 2), 16))
                                                         .ToArray();

                            // 解析设备数据
                            DeviceData deviceData = UtilClass.GetDeviceData(byteArray);
                            //电量
                            deviceModel.battery = UtilClass.GetBattery(my_text);
                            //是否佩戴
                            deviceModel.wearPatch = UtilClass.IsWearPatch(my_text);

                            UpdateDeviceCache(deviceModel.EegList, deviceData.EegList, 125);

                            if (deviceData.AccList != null && deviceData.AccList.Count > 0)
                            {
                                // 提取加速度数据
                                float accX = deviceData.AccList[0];
                                float accY = deviceData.AccList.Count > 1 ? deviceData.AccList[1] : default;
                                float accZ = deviceData.AccList.Count > 2 ? deviceData.AccList[2] : default;

                                // 提取角速度数据（假设 gyrList 至少有一个元素）
                                float gyrX = deviceData.GyrList != null && deviceData.GyrList.Count > 0 ? deviceData.GyrList[0] : default;

                                // 更新加速度数据
                                UpdateDeviceCache(deviceModel.AccList, deviceData.AccList, 15);

                                // 更新角速度数据
                                UpdateDeviceCache(deviceModel.GyrList, new List<float> { gyrX }, 15);

                                // 更新计算体位需要的 x, y, z
                                UpdateDeviceCache(deviceModel.AccData.AccX, new List<float> { accX }, 5);
                                UpdateDeviceCache(deviceModel.AccData.AccY, new List<float> { accY }, 5);
                                UpdateDeviceCache(deviceModel.AccData.AccZ, new List<float> { accZ }, 5);
                            }

                            if (deviceModel.EegList.Count >= 125)
                            {
                                string my_show = JsonConvert.SerializeObject(deviceModel);
                                LogHelper.WriteLog("解析后的数据->>" + my_show);

                                // LogHelper.WriteLog($"初始化结果: {slp.InitializeSLP()}");

                                // 准备测试数据
                                //var eegData = Enumerable.Range(1, 2500).Select(j => (float)j).ToArray();
                                //var accX = Enumerable.Range(1, 100).Select(j => 0.1f * j).ToArray();
                                //var accY = Enumerable.Range(1, 100).Select(j => 0.2f * j).ToArray();
                                //var accZ = Enumerable.Range(1, 100).Select(j => 0.3f * j).ToArray();
                                var eegData = deviceModel.EegList.ToArray();
                                var accX = deviceModel.AccData.AccX.ToArray();
                                var accY = deviceModel.AccData.AccY.ToArray();
                                var accZ = deviceModel.AccData.AccZ.ToArray();

                                LogHelper.WriteLog("数据准备完成，开始调用计算...");
                                string my_parse_data = slp.CalculateSLP(eegData, accX, accY, accZ, 2000.0f);
                                if (my_parse_data != "-1")
                                {
                                    FlexoData my_flexodata = JsonConvert.DeserializeObject<FlexoData>(my_parse_data);
                                    if (my_flexodata != null)
                                    {
                                        string my_str_flexodata = JsonConvert.SerializeObject(my_flexodata);

                                        _webSocketServerService.SendMessageToAllAsync(my_str_flexodata);
                                    }
                                }
                                // LogHelper.WriteLog($"计算结果: my_parse_data");


                                //Console.WriteLine(my_show);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }

        /// <summary>
        /// 更新设备数据缓存。
        /// </summary>
        /// <param name="dataList">要更新的数据缓存列表。</param>
        /// <param name="newList">要添加的新数据列表。</param>
        /// <param name="maxLength">缓存列表的最大长度。</param>
        public void UpdateDeviceCache(List<float> dataList, List<float> newList, int maxLength)
        {
            try
            {
                if (dataList == null)
                {
                    throw new ArgumentNullException(nameof(dataList), "Data list cannot be null.");
                }
                if (newList == null)
                {
                    throw new ArgumentNullException(nameof(newList), "New data list cannot be null.");
                }

                // 添加新数据到缓存列表
                dataList.AddRange(newList);

                // 如果超过最大长度，移除最早的元素
                while (dataList.Count > maxLength)
                {
                    dataList.RemoveAt(0);
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }

        /// <summary>
        /// 发送数据接口
        /// </summary>
        /// <returns></returns>
        public async Task Write(byte[] data)
        {
            try
            {
                if (CurrentWriteCharacteristic != null)
                {
                    CurrentWriteCharacteristic.WriteValueAsync(CryptographicBuffer.CreateFromByteArray(data), GattWriteOption.WriteWithResponse);
                    string str = "发送数据：" + BitConverter.ToString(data);
                    this.MessAgeChanged(MsgType.BleData, str, data);
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }
    }
}
